package org.go.trigger;

import java.util.Date;

import org.go.scheduler.ScheduleBuilder;
import org.go.util.Key;
import org.go.work.WorkDataMap;
import org.go.work.WorkKey;

/**
 * 
 * @author hejie
 *
 * @param <T>
 */
public class TriggerBuilder<T extends Trigger> {
	private static String type;

	public static TriggerBuilder<Trigger> newTrigger(String trrigerType) {
		type = trrigerType;
		return new TriggerBuilder<Trigger>();
	}

	private String calendarName;
	private String description;
	private Date endTime;
	//private String id;
	private TriggerKey key;
	private int priority = Trigger.DEFAULT_PRIORITY;
	private ScheduleBuilder scheduleBuilder = null;
	private Date startTime = new Date();

	private TriggerBuilder() {

	}

	public T build() {
		if (scheduleBuilder == null)
			scheduleBuilder = RepeatScheduleBuilder.repeatSchedule();
		Trigger trig = scheduleBuilder.build(type);

		if (calendarName != null) {
			trig.setCalendarName(calendarName);
		}
		if (description != null) {
			trig.setDescription(description);
		}
		if (endTime != null) {
			trig.setEndTime(endTime);
		}
		if (key == null) {
			key = new TriggerKey(Key.createUniqueName(null), null);
		}
		trig.setTriggerKey(key);
		trig.setPriority(priority);
		trig.setStartTime(startTime);
		if (scheduleBuilder instanceof RepeatScheduleBuilder) {
			RepeatScheduleBuilder builder = (RepeatScheduleBuilder) scheduleBuilder;
			trig.setInterval(builder.getInterval());
		}
		//if (!jobDataMap.isEmpty())
		//	trig.setJobDataMap(jobDataMap);

		return (T) trig;
	}

	//	public TriggerBuilder<T> forWorker(String jobName, String jobGroup) {
	//		this.jobKey = new WorkKey(jobName, jobGroup);
	//		return this;
	//	}

	@SuppressWarnings("hiding")
	public TriggerBuilder<T> endAt(Date endTime) {
		this.endTime = endTime;
		return this;
	}

	//	public TriggerBuilder<T> forWorker(WorkerDesc jobDetail) {
	//		WorkKey k = jobDetail.getKey();
	//		if (k.getName() == null)
	//			throw new IllegalArgumentException("The given job has not yet had a name assigned to it.");
	//		//this.setJobKey(k);
	//		return this;
	//	}

	public TriggerBuilder forJob(WorkKey jobKey) {
		return null;
	}

	public String getCalendarName() {
		return calendarName;
	}

	public String getDescription() {
		return description;
	}

	public Date getEndTime() {
		return endTime;
	}

	public TriggerKey getKey() {
		return key;
	}

	public int getPriority() {
		return priority;
	}

	public ScheduleBuilder getScheduleBuilder() {
		return scheduleBuilder;
	}

	public Date getStartTime() {
		return startTime;
	}

	@SuppressWarnings("hiding")
	public TriggerBuilder<T> modifiedByCalendar(String calendarName) {
		this.calendarName = calendarName;
		return this;
	}

	public void setCalendarName(String calendarName) {
		this.calendarName = calendarName;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}

	public void setKey(TriggerKey key) {
		this.key = key;
	}

	public void setPriority(int priority) {
		this.priority = priority;
	}

	public void setScheduleBuilder(ScheduleBuilder scheduleBuilder) {
		this.scheduleBuilder = scheduleBuilder;
	}

	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}

	public TriggerBuilder<T> startAt(@SuppressWarnings("hiding") Date startTime) {
		this.startTime = startTime;
		return this;
	}

	//	public TriggerBuilder<T> withId(String aId) {
	//		//this.id = aId;
	//		return this;
	//	}

	public void usingJobData(WorkDataMap jobDataMap) {
	}

	public TriggerBuilder<T> withDescription(String description1) {
		this.description = description1;
		return this;
	}

	public TriggerBuilder<T> withIdentity(String id, String aid) {
		setKey(new TriggerKey(id, aid));
		//setId(aid);
		return this;
	}

	public TriggerBuilder withIdentity(TriggerKey triggerKey) {
		return null;
	}

	@SuppressWarnings("hiding")
	public TriggerBuilder<T> withPriority(int priority) {
		this.setPriority(priority);
		return this;
	}

	@SuppressWarnings("hiding")
	public <SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> scheduleBuilder) {
		this.setScheduleBuilder(scheduleBuilder);
		return (TriggerBuilder<SBT>) this;
	}
}
